package com.android.people;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;

public class PhotoDatabaseHelper extends SQLiteOpenHelper {
    private static final String TAG = "PhotoDatabaseHelper";
    private static final boolean DEBUG = false;
    
    public static final String DATABASE_NAME = "preview-gallary.db";
    public static final int DATABASE_VERSION = 2;

    static final String TABLE_PHOTOS = "photos";
    static final String FIELD_FILE_ID = "fileId";
    static final String FIELD_PHOTO_BLOB = "photoBlob";

    static final String[] PHOTOS_PROJECTION = {
        FIELD_PHOTO_BLOB,
    };
    
    static final int INDEX_PHOTO_BLOB = 0;
    
    PhotoDatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        LOGD("create the database");
        db.execSQL("CREATE TABLE " + TABLE_PHOTOS + " (" +
                   FIELD_FILE_ID + " INTEGER PRIMARY KEY," +
                   FIELD_PHOTO_BLOB + " BLOB" +
                    ");");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        LOGD(" update the data base");
        int version = oldVersion;
        if (version != DATABASE_VERSION) {
            LOGD("Destroying all old data.");
            db.execSQL("DROP TABLE IF EXISTS " + TABLE_PHOTOS);
            onCreate(db);
        }
    }

    public boolean contain(long fileId) {
        Cursor c = null;
        try {
            SQLiteDatabase db = getWritableDatabase();
            String selection = String.format("%s='%d'", FIELD_FILE_ID, fileId);
            c = db.query(TABLE_PHOTOS, null, selection, null, null, null, null, null);
            if (c != null && c.getCount() == 1) {
                LOGD("The database contain the file : " + fileId);
                return true;
            }
        } catch (SQLiteException e) {
            LOGD("Could not open database " + e.getMessage());
        } finally {
            if (c != null) {
                c.close();
            }
        }
        return false;
    }
    
    public List<Long> getFileIdList() {
        List<Long> ret = new ArrayList<Long>();
        Cursor c = null;
        try {
            SQLiteDatabase db = getWritableDatabase();
            c = db.query(TABLE_PHOTOS, new String[] { FIELD_FILE_ID }, null, null, null, null, null);
            if (c != null) {
                c.moveToFirst();
                int count = c.getCount();
                for (int index = 0; index < count; ++index) {
                    ret.add(c.getLong(0));
                    if (c.moveToNext() == false) {
                        break;
                    }
                }
            }
        } catch (SQLiteException e) {
            LOGD("Could not open database " + e.getMessage());
        } finally {
            if (c != null) {
                c.close();
            }
        }
        return ret;
    }
    
    /**
     * Store the given bitmap in this database for the given appWidgetId.
     */
    public boolean setPhoto(long fileId, Bitmap bitmap) {
        LOGD("set phote file name " + fileId);
        boolean success = false;
        try {
            int size = bitmap.getWidth() * bitmap.getHeight() * 4;
            ByteArrayOutputStream out = new ByteArrayOutputStream(size);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
            out.flush();
            out.close();

            ContentValues values = new ContentValues();
            values.put(FIELD_FILE_ID, fileId);
            values.put(FIELD_PHOTO_BLOB, out.toByteArray());

            SQLiteDatabase db = getWritableDatabase();
            db.insertOrThrow(TABLE_PHOTOS, null, values);

            success = true;
            LOGD("insert the file : " + fileId + " success");
        } catch (SQLiteException e) {
            LOGD("Could not open database " + e.getMessage());
        } catch (IOException e) {
            LOGD("Could not serialize photo" + e.getMessage());
        }
        return success;
    }
    
    /**
     * Inflate and return a bitmap for the given appWidgetId.
     */
    public Bitmap getPhoto(long fileId) {
        Cursor c = null;
        Bitmap bitmap = null;
        try {
            SQLiteDatabase db = getReadableDatabase();
            String selection = String.format("%s=%d", FIELD_FILE_ID, fileId);
            c = db.query(TABLE_PHOTOS, PHOTOS_PROJECTION, selection, null,
                    null, null, null, null);

            if (c != null) {
                LOGD("getPhoto query count = " + c.getCount());
            }

            if (c != null && c.moveToFirst()) {
                byte[] data = c.getBlob(INDEX_PHOTO_BLOB);
                if (data != null) {
                    bitmap = BitmapFactory.decodeByteArray(data, 0,
                            data.length);
                }
            }
        } catch (SQLiteException e) {
            LOGD("Could not load photo from database " + e.getMessage());
        } finally {
            if (c != null) {
                c.close();
            }
            close();
        }
        return bitmap;
    }

    /**
     * Remove any bitmap associated with the given appWidgetId.
     */
    public void deletePhoto(long fileId) {
        try {
            SQLiteDatabase db = getWritableDatabase();
            String whereClause = String.format("%s=%d", FIELD_FILE_ID, fileId);
            db.delete(TABLE_PHOTOS, whereClause, null);
            db.close();
        } catch (SQLiteException e) {
            LOGD("Could not delete photo from database" + e.getMessage());
        }
    }
    
    public void deleteAllPhoto() {
        List<Long> fileList = this.getFileIdList();
        for (long filename : fileList) {
            deletePhoto(filename);
        }
    }
    
    public static void LOGD(String msg) {
        if (DEBUG) {
            Log.d(TAG, msg);
        }
    }
    
}